#include "Rp2LightingEffect.h"

using namespace Rp2;

RP2_IMPLEMENT_RTTI(Rp2, LightingEffect, ShaderEffect);
RP2_IMPLEMENT_DEFAULT_NAME_ID(LightingEffect, ShaderEffect);

//---------------------------------------------------------------------------------------------------
LightingEffect::LightingEffect(int iPass)
	:
	ShaderEffect(iPass)
{
    // If no lights are attached, the Configure() call will turn the effect
    // off.	
}
//---------------------------------------------------------------------------------------------------
LightingEffect::~LightingEffect()
{
}
//---------------------------------------------------------------------------------------------------
void LightingEffect::AttachLight(Light* pkLight)
{
	assert(pkLight);

	// check if the light is already in the list
	for (int i = 0; i < (int)m_kLights.size(); i++)
	{
		if (m_kLights[i] == pkLight)
		{
            // The light already exists, so do nothing.
            return;
		}
	}

    // The light is not in the current list, so add it.
    m_kLights.push_back(pkLight);
}
//---------------------------------------------------------------------------------------------------
void LightingEffect::DetachLight (Light* pkLight)
{
    std::vector<LightPtr>::iterator pkIter = m_kLights.begin();
    for (/**/; pkIter != m_kLights.end(); pkIter++)
    {
        if (pkLight == *pkIter)
        {
            m_kLights.erase(pkIter);
            return;
        }
    }
}
//---------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------
void LightingEffect::SetGlobalState(int iPass, Renderer* pkRenderer, bool bPrimaryEffect)
{
    ShaderEffect::SetGlobalState(iPass,pkRenderer,bPrimaryEffect);
	
	MaterialState* pkMS = pkRenderer->GetMaterialState();
	if (iPass == 0)
	{
		m_kSaveEmissive = pkMS->Emissive;
	}
	else
	{
        pkMS->Emissive = ColorRGB::BLACK;
	}

	for (int i = 0; i < (int)m_kLights.size(); i++)
	{
		pkRenderer->SetLight(i, m_kLights[i]);
	}
}
//---------------------------------------------------------------------------------------------------
void LightingEffect::RestoreGlobalState(int iPass, Renderer* pkRenderer, bool bPrimaryEffect)
{
    ShaderEffect::RestoreGlobalState(iPass,pkRenderer,bPrimaryEffect);
	
	for (int i = 0; i < (int)m_kLights.size(); i++)
	{
		pkRenderer->SetLight(i, 0);
	}

	if (iPass == m_iPassQuantity - 1)
	{
        MaterialState* pkMS = pkRenderer->GetMaterialState();
        pkMS->Emissive = m_kSaveEmissive;
	}
}
//---------------------------------------------------------------------------------------------------
// void LightingEffect::Configure()
// {
//     if (m_kLights.size() == 0)
//     {
//         SetPassQuantity(1);
//         m_kVShader[0] = new VertexShader("Material");
//         m_kPShader[0] = new PixelShader("PassThrough4");
//         return;
//     }
// 
// 	// Use a bucket sort on the lights to arrange them in the order:
//     // ambient, directional, point, spot.
// 	std::vector<LightPtr> m_akBucket[4];
// 	int iLQuantity = (int)m_kLights.size();
// 	int i, iType;
// 	for (i = 0; i < iLQuantity; i++)
// 	{
// 		iType = (int)m_kLights[i]->Type;
// 		m_akBucket[iType].push_back(m_kLights[i]);
// 	}
// 
//     // For multipass rendering.  The default is to use additive blending, but
//     // you can change the blending modes, if so desired, in your application
//     // code.
//     SetPassQuantity(iLQuantity);
// 	for (i = 1; i < iLQuantity; i++)
// 	{
// 		AlphaState* pkAS= m_kAlphaState[i];
// 		pkAS->BlendEnabled = true;
// 		pkAS->SrcBlend = AlphaState::SBF_ONE;
// 		pkAS->DstBlend = AlphaState::DBF_ONE;
// 	}
// 
//     const char acType[4] = { 'a', 'd', 'p', 's' };
// 	std::string kShaderName("L1$");
// 	int iLight = 0;
// 	for (iType = 0; iType < 4; iType++)
// 	{
// 		for (i = 0; i < (int)m_akBucket[iType].size(); i++)
// 		{
// 			kShaderName[2] = acType[iType];
// 			assert(!m_kVShader[iLight]);
// 			m_kVShader[iLight] = new VertexShader(kShaderName);
// 			assert(!m_kPShader[iLight]);
// 			m_kPShader[iLight] = new PixelShader("PassThrough4");
// 			iLight++;
// 		}
// 	}
// }
//---------------------------------------------------------------------------------------------------